package com.elinkway.infinitemovies.utils;

import android.content.Context;

import com.elinkway.infinitemovies.application.MoviesApplication;
import com.elinkway.infinitemovies.bigdata.BigDataUtils;
import com.elinkway.infinitemovies.config.SettingManage;
import com.elinkway.infinitemovies.dao.PreferencesManager;
import com.elinkway.infinitemovies.ui.activity.LoginActivity;

import java.util.ArrayList;
import java.util.List;

/**
 * Author: liuxiaojiang(liuxiaojiang@lvideo.com)
 * Date: 2016-04-27
 * Time: 10:15
 * Description: 播放数据的上报处理类
 */
public class PlayDataReporter {

    private String netType = "";
    private String sessionId = "";
    private String os = "";
    private String resolution = "";
    private String vid = "";
    private String source = "";
    //这里的时间大多都有绝对时间(ab,世界时间)和相对时间(re,在视频中的时间)的区别
    private long startAbTs;
    private long errorReTs = -1;
    private List<PlayPeriod> playPeriods = new ArrayList<PlayPeriod>();
    private List<PlayBuffer> playBuffers = new ArrayList<PlayBuffer>();

    private String uploadVersion = "1";
    private String aid = "";
    private String mid = "";
    private String cloudId = "";
    private String globalVid = "";
    private String porder = "";
    private long totalTime;
    private String vt = "";

    public String getUploadVersion() {
        return uploadVersion;
    }

    public void setUploadVersion(String uploadVersion) {
        this.uploadVersion = uploadVersion;
    }

    public String getAid() {
        return aid;
    }

    public void setAid(String aid) {
        this.aid = aid;
    }

    public String getMid() {
        return mid;
    }

    public void setMid(String mid) {
        this.mid = mid;
    }

    public String getCloudId() {
        return cloudId;
    }

    public void setCloudId(String cloudId) {
        this.cloudId = cloudId;
    }

    public String getGlobalVid() {
        return globalVid;
    }

    public void setGlobalVid(String globalVid) {
        this.globalVid = globalVid;
    }

    public String getPorder() {
        return porder;
    }

    public void setPorder(String porder) {
        this.porder = porder;
    }

    public long getTotalTime() {
        return totalTime;
    }

    public void setTotalTime(long totalTime) {
        this.totalTime = totalTime;
    }

    public String getVt() {
        return vt;
    }

    public void setVt(String vt) {
        this.vt = vt;
    }

    public PlayDataReporter(){
        sessionId = PlayDataUtil.getNewSessionId();
        startAbTs = System.currentTimeMillis();
    }

    /**
     * 播放时间段
     */
    public class PlayPeriod{
        long abPlayTs;
        long abPauseTs;
        long rePlayTs;
        long rePauseTs;

        public long getAbPlayTs() {
            return abPlayTs;
        }

        public void setAbPlayTs(long abPlayTs) {
            this.abPlayTs = abPlayTs;
        }

        public long getAbPauseTs() {
            return abPauseTs;
        }

        public void setAbPauseTs(long abPauseTs) {
            this.abPauseTs = abPauseTs;
        }

        public long getRePlayTs() {
            return rePlayTs;
        }

        public void setRePlayTs(long rePlayTs) {
            this.rePlayTs = rePlayTs;
        }

        public long getRePauseTs() {
            return rePauseTs;
        }

        public void setRePauseTs(long rePauseTs) {
            this.rePauseTs = rePauseTs;
        }
    }

    /**
     * 卡顿的时间段
     */
    public class PlayBuffer{
        long abBufferStartTs;   //buffer start time(system time)
        long abBufferEndTs;     //buffer end time(system time)
        long reBufferTs;        //buffer time(in the whole duration)

        public long getAbBufferStartTs() {
            return abBufferStartTs;
        }

        public void setAbBufferStartTs(long abBufferStartTs) {
            this.abBufferStartTs = abBufferStartTs;
        }

        public long getAbBufferEndTs() {
            return abBufferEndTs;
        }

        public void setAbBufferEndTs(long abBufferEndTs) {
            this.abBufferEndTs = abBufferEndTs;
        }

        public long getReBufferTs() {
            return reBufferTs;
        }

        public void setReBufferTs(long reBufferTs) {
            this.reBufferTs = reBufferTs;
        }
    }

    public String getNetType() {
        return netType;
    }

    public void setNetType(String netType) {
        this.netType = netType;
    }

    public String getOs() {
        return os;
    }

    public void setOs(String os) {
        this.os = os;
    }

    public String getResolution() {
        return resolution;
    }

    public void setResolution(String resolution) {
        this.resolution = resolution;
    }

    public String getVid() {
        return vid;
    }

    public void setVid(String vid) {
        this.vid = vid;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public long getStartAbTs() {
        return startAbTs;
    }

    public void setStartAbTs(long startAbTs) {
        this.startAbTs = startAbTs;
    }

    public long getErrorReTs() {
        return errorReTs;
    }

    public void setErrorReTs(long errorReTs) {
        this.errorReTs = errorReTs;
    }

    public void addPlayPeriod(PlayPeriod period){
        playPeriods.add(period);
    }

    public void addPlayBuffer(PlayBuffer buffer){
        playBuffers.add(buffer);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        String devicedata = MoviesUtils.getmDeviceId() + "," + MoviesConstant.UUID + "," +
                MoviesApplication.getInstance().getSharedPreferences(SettingManage.LOGIN_INFO, Context.MODE_PRIVATE).getString(LoginActivity.UID, "") + "," +
                MoviesUtils.getDeviceModel() + "," + MoviesUtils.getResolution(MoviesApplication.getInstance()) + "," +
                "Android " + MoviesUtils.getOSVersion() + "," + BigDataUtils.getNetType(MoviesApplication.getInstance()) + "," +
                PlayDataUtil.getSimOperatorInfo() + "," + PreferencesManager.getInstance().getPublicIp() + "," +
                SharePreferenceManager.getVaule(MoviesApplication.getInstance(), MyLocationManager.LOCATIONKEY, "") + ",";

        StringBuilder playTimeSb = new StringBuilder();
        if(playPeriods != null && playPeriods.size() > 0){
            for (int i = 0; i < playPeriods.size(); i++){
                //处理时间跳帧情况。
                if(playPeriods.get(i).getRePauseTs() < playPeriods.get(i).getRePlayTs()){
                    playPeriods.get(i).setRePauseTs(playPeriods.get(i).getRePlayTs());
                }
                playTimeSb.append(playPeriods.get(i).getAbPlayTs() + "," + playPeriods.get(i).getRePlayTs() + "," +
                        playPeriods.get(i).getAbPauseTs() + "," + playPeriods.get(i).getRePauseTs());
                if(i != playPeriods.size() - 1){
                    playTimeSb.append(";");
                }
            }
        }

        long playabTime = startAbTs;
        long playreTime = 0;
        long endabTime = startAbTs;
        long endreTime = 0;
        long allPlayTime = 0;

        if(playPeriods != null && playPeriods.size() > 0){
            if(playPeriods.get(0) != null){
                playabTime = playPeriods.get(0).getAbPlayTs();
                playreTime = playPeriods.get(0).getRePlayTs();
            }
            if(playPeriods.get(playPeriods.size() - 1) != null){
                endabTime = playPeriods.get(playPeriods.size() - 1).getAbPauseTs();
                endreTime = playPeriods.get(playPeriods.size() - 1).getRePauseTs();
            }
            allPlayTime = calculatePlayTime(playPeriods);
        }
        long waitingTime = playabTime - startAbTs;

        //卡顿数据的计算
        long pBufferTime = 0;
        int bufferTimes = 0;
        long averageInterval = 0;

        StringBuilder bufferTimeSb = new StringBuilder();
        if(playBuffers != null && playBuffers.size() > 0){
            bufferTimes = playBuffers.size();
            long allBufferTime = 0;
            long allBufferInterTime = 0;
            for (int i = 0 ;i < playBuffers.size(); i++){
                bufferTimeSb.append(playBuffers.get(i).getAbBufferStartTs() + "," +
                        playBuffers.get(i).getAbBufferEndTs() + "," + playBuffers.get(i).getReBufferTs());
                if(i != playBuffers.size() - 1){
                    bufferTimeSb.append(";");
                }
                allBufferTime += playBuffers.get(i).getAbBufferEndTs() - playBuffers.get(i).getAbBufferStartTs();
                if(i > 0){
                    allBufferInterTime += playBuffers.get(i).getAbBufferStartTs() - playBuffers.get(i-1).getAbBufferEndTs();
                }
            }
            pBufferTime = allBufferTime/bufferTimes;
            if(bufferTimes > 1){
                averageInterval = allBufferInterTime/(bufferTimes - 1);
            }
        }

        String sessiondata = uploadVersion + "," + sessionId + ","+ aid + "," + mid + "," + cloudId + "," +
                globalVid + "," + porder + "," + vid + "," + source + "," + totalTime + "," +
                startAbTs + "," + errorReTs + "," + playabTime + "," +
                playreTime + "," + waitingTime + "," + endabTime + "," + endreTime + "," + allPlayTime + "," +
                pBufferTime + "," + bufferTimes + "," + averageInterval;

        sb.append(devicedata).append(sessiondata).append("&").append(playTimeSb.toString());
        if(playBuffers != null && playBuffers.size() > 0){
            sb.append("&").append(bufferTimeSb.toString());
        }
        return sb.toString();
    }

    private long calculatePlayTime(List<PlayPeriod> playPeriods) {
        if(playPeriods.size() == 1){
            return playPeriods.get(0).getRePauseTs() - playPeriods.get(0).getRePlayTs();
        }else{
            sortPeriods(playPeriods);
            return getAllPlayTime(playPeriods);
        }
    }

    /**
     * 计算总播放时间
     * @param playPeriods
     * @return
     */
    private long getAllPlayTime(List<PlayPeriod> playPeriods) {
        PlayPeriod temp = playPeriods.get(0);
        long allTime = playPeriods.get(0).getRePauseTs() - playPeriods.get(0).getRePlayTs();
        for (int i = 0; i < playPeriods.size() - 1; i++){
            if(temp.getRePauseTs() < playPeriods.get(i + 1).getRePlayTs()){
                //不重叠
                allTime = allTime + (playPeriods.get(i + 1).getRePauseTs() - playPeriods.get(i + 1).getRePlayTs());
                temp.setRePauseTs(playPeriods.get(i + 1).getRePauseTs());
            }else if(temp.getRePauseTs() > playPeriods.get(i + 1).getRePlayTs() && temp.getRePauseTs() < playPeriods.get(i + 1).getRePauseTs()){
                //部分重叠
                allTime = allTime + (playPeriods.get(i + 1).getRePauseTs() - temp.getRePauseTs());
                temp.setRePauseTs(playPeriods.get(i + 1).getRePauseTs());
            }else{

            }
        }
        return allTime;
    }

    /**
     * 对播放片段进行排序，以相对开始时间作比较
     * @param playPeriods
     */
    private void sortPeriods(List<PlayPeriod> playPeriods) {
        PlayPeriod temp = null;
        for(int i = 0; i < playPeriods.size() - 1; i++){
            for(int j = 0; j < playPeriods.size() - 1 - i; j++){
                if(playPeriods.get(j).getRePlayTs() > playPeriods.get(j+1).getRePlayTs()){
                    temp = playPeriods.get(j);
                    playPeriods.set(j, playPeriods.get(j + 1));
                    playPeriods.set(j+1, temp);
                }
            }
        }
    }
}
